package cn.edu.swu.miniwebsvr.core;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
    private final Config config = Config.getInstance();
    private final ExecutorService threadPool = Executors.newFixedThreadPool(10);
    private volatile boolean isRunning = false;
    private ServerSocket serverSocket;

    public void start() {
        // TODO: [222024321072050/邓琳馨] 实现 ServerSocket 的创建和监听
        // 防止重复启动
        if (isRunning) {
            System.out.println("服务器已经在运行中");
            return;
        }

        isRunning = true;

        try {
            serverSocket = new ServerSocket(config.getPort());
            System.out.println("MiniWebSvr 启动成功，监听端口：" + config.getPort());
            System.out.println("Web根目录：" + config.getWebRoot());
            System.out.println("服务器运行中，按 Ctrl+C 停止服务");

            // 添加关闭钩子，确保优雅关闭
            Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown));

            while (isRunning) {
                try {
                    Socket clientSocket = serverSocket.accept();
                    System.out.println("接收到新的连接：" + clientSocket.getInetAddress().getHostAddress() + ":" + clientSocket.getPort());

                    // 提交到线程池处理
                    threadPool.execute(new RequestProcessor(clientSocket));

                } catch (IOException e) {
                    if (isRunning) {
                        System.err.println("接受客户端连接时发生异常: " + e.getMessage());
                    }
                    // 如果服务器正在关闭，忽略异常
                }
            }
        } catch (IOException e) {
            System.err.println("服务器启动失败，端口 " + config.getPort() + " 可能已被占用: " + e.getMessage());
        } finally {
            shutdown();
        }
    }

    /**
     * 优雅关闭服务器
     */
    public void shutdown() {
        if (!isRunning) {
            return;
        }

        isRunning = false;
        System.out.println("正在关闭服务器...");

        // 关闭ServerSocket
        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                System.err.println("关闭ServerSocket时发生异常: " + e.getMessage());
            }
        }

        // 关闭线程池
        threadPool.shutdown();
        System.out.println("服务器已关闭");
    }

    private static class RequestProcessor implements Runnable {
        private final Socket socket;

        public RequestProcessor(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            // TODO: [222024321072050/邓琳馨] 完善请求处理流程，确保异常安全和资源关闭
            // 确保资源被正确关闭
            try (socket) { // Java 9+ 的try-with-resources语法
                // 设置socket超时时间，防止客户端长时间不发送数据
                socket.setSoTimeout(30000); // 30秒超时

                // 解析HTTP请求
                Parameter request = HttpParser.parse(socket.getInputStream());

                if (request != null) {
                    System.out.println("处理请求: " + request.getMethod() + " " + request.getUrl());

                    // 路由处理
                    Router router = new Router();
                    router.route(request, socket.getOutputStream());

                    System.out.println("请求处理完成: " + request.getMethod() + " " + request.getUrl());
                } else {
                    // 解析失败，返回400错误
                    sendErrorResponse(400, "Bad Request");
                }

            } catch (IOException e) {
                System.err.println("IO异常处理请求: " + e.getMessage());
                // 尝试返回500错误响应
                try {
                    sendErrorResponse(500, "Internal Server Error");
                } catch (IOException ex) {
                    // 如果连错误响应都无法发送，只能记录日志
                    System.err.println("无法发送错误响应: " + ex.getMessage());
                }
            } catch (Exception e) {
                // TODO: [222024321072050/邓琳馨] 可以在这里实现返回 500 错误页面的逻辑
                System.err.println("处理请求时发生未预期异常: " + e.getMessage());
                e.printStackTrace();
                // 尝试返回500错误响应
                try {
                    sendErrorResponse(500, "Internal Server Error");
                } catch (IOException ex) {
                    System.err.println("无法发送错误响应: " + ex.getMessage());
                }
            }
        }

        /**
         * 发送错误响应
         */
        private void sendErrorResponse(int statusCode, String statusMessage) throws IOException {
            String response = "HTTP/1.1 " + statusCode + " " + statusMessage + "\r\n" +
                    "Content-Type: text/html; charset=utf-8\r\n" +
                    "Connection: close\r\n" +
                    "\r\n" +
                    "<html><head><title>" + statusCode + " " + statusMessage + "</title></head>" +
                    "<body><h1>" + statusCode + " " + statusMessage + "</h1>" +
                    "<p>服务器处理请求时发生错误</p></body></html>";

            socket.getOutputStream().write(response.getBytes("UTF-8"));
            socket.getOutputStream().flush();
        }
    }

    /**
     * 主方法，启动服务器
     */
    public static void main(String[] args) {
        Server server = new Server();
        server.start();
    }
}